package com.vehiclemanagement.service.impl;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.vehiclemanagement.entity.InsuranceRecord;
import com.vehiclemanagement.mapper.InsuranceRecordMapper;
import com.vehiclemanagement.service.InsuranceRecordService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.List;
import java.util.Map;

/**
 * 车辆保险记录服务实现类
 */
@Service
@Slf4j
public class InsuranceRecordServiceImpl extends ServiceImpl<InsuranceRecordMapper, InsuranceRecord> implements InsuranceRecordService {

    @Autowired
    private InsuranceRecordMapper insuranceRecordMapper;

    @Override
    public IPage<InsuranceRecord> pageInsurances(Integer current, Integer size, String searchTerm,
                                              Long vehicleId, Integer insuranceType, Integer status,
                                              LocalDateTime startTime, LocalDateTime endTime) {
        Page<InsuranceRecord> page = new Page<>(current, size);
        StringBuilder whereSql = new StringBuilder();
        whereSql.append(" ir.del_flag = 0 ");

        if (StringUtils.hasText(searchTerm)) {
            whereSql.append(" AND (v.plate_number LIKE '%").append(searchTerm).append("%'")
                    .append(" OR ir.insurance_company LIKE '%").append(searchTerm).append("%'")
                    .append(" OR ir.policy_number LIKE '%").append(searchTerm).append("%')");
        }

        if (vehicleId != null) {
            whereSql.append(" AND ir.vehicle_id = ").append(vehicleId);
        }

        if (insuranceType != null) {
            whereSql.append(" AND ir.insurance_type = ").append(insuranceType);
        }

        if (status != null) {
            whereSql.append(" AND ir.status = ").append(status);
        }

        if (startTime != null) {
            whereSql.append(" AND ir.start_time >= '").append(startTime).append("'");
        }

        if (endTime != null) {
            whereSql.append(" AND ir.end_time <= '").append(endTime).append("'");
        }

        return insuranceRecordMapper.selectPageWithInfo(page, whereSql.toString());
    }

    @Override
    public InsuranceRecord getInsuranceById(Long id) {
        InsuranceRecord insurance = getById(id);
        if (insurance == null) {
            log.error("保险记录不存在, id: {}", id);
            return null;
        }

        // 计算剩余天数
        if (insurance.getEndTime() != null) {
            LocalDateTime now = LocalDateTime.now();
            LocalDateTime endTime = insurance.getEndTime();
            long remainingDays = ChronoUnit.DAYS.between(now, endTime);
            insurance.setRemainingDays(remainingDays);
        }

        return insurance;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addInsurance(InsuranceRecord insurance) {
        if (insurance == null) {
            log.error("添加保险记录失败: insurance不能为空");
            return false;
        }

        // 设置默认值
        insurance.setCreateTime(LocalDateTime.now());
        insurance.setUpdateTime(LocalDateTime.now());
        insurance.setDelFlag(0);

        // 设置理赔次数默认值
        if (insurance.getClaimCount() == null) {
            insurance.setClaimCount(0);
        }

        // 设置总理赔金额默认值
        if (insurance.getTotalClaimAmount() == null) {
            insurance.setTotalClaimAmount(BigDecimal.ZERO);
        }

        // 设置状态
        setInsuranceStatus(insurance);

        boolean result = save(insurance);
        log.info("添加保险记录 {} ", result ? "成功" : "失败");
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateInsurance(InsuranceRecord insurance) {
        if (insurance == null || insurance.getId() == null) {
            log.error("更新保险记录失败: insurance或ID不能为空");
            return false;
        }

        // 设置状态
        setInsuranceStatus(insurance);

        insurance.setUpdateTime(LocalDateTime.now());
        boolean result = updateById(insurance);
        log.info("更新保险记录 {} , id: {}", result ? "成功" : "失败", insurance.getId());
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteInsurance(Long id) {
        if (id == null) {
            log.error("删除保险记录失败: ID不能为空");
            return false;
        }

        int result = insuranceRecordMapper.deletePhysically(id);
        log.info("删除保险记录 {} , id: {}", result > 0 ? "成功" : "失败", id);
        return result > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateAllInsuranceStatus() {
        int count = insuranceRecordMapper.updateInsuranceStatus();
        log.info("更新保险状态完成，更新记录数: {}", count);
        return count;
    }

    @Override
    public List<InsuranceRecord> getExpiringInsurance(Integer days) {
        if (days == null || days <= 0) {
            days = 30; // 默认30天
        }
        return insuranceRecordMapper.selectExpiringInsurance(days);
    }

    @Override
    public List<InsuranceRecord> getExpiredInsurance() {
        return insuranceRecordMapper.selectExpiredInsurance();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addClaim(Long id, BigDecimal claimAmount) {
        if (id == null) {
            log.error("增加理赔次数和金额失败: ID不能为空");
            return false;
        }

        if (claimAmount == null || claimAmount.compareTo(BigDecimal.ZERO) <= 0) {
            log.error("增加理赔次数和金额失败: 理赔金额必须大于0");
            return false;
        }

        int result = insuranceRecordMapper.incrementClaimCount(id, claimAmount);
        log.info("增加理赔次数和金额 {} , id: {}, 金额: {}", result > 0 ? "成功" : "失败", id, claimAmount);
        return result > 0;
    }

    @Override
    public BigDecimal sumPremiumByVehicleId(Long vehicleId) {
        if (vehicleId == null) {
            log.error("计算车辆总保费失败: vehicleId不能为空");
            return BigDecimal.ZERO;
        }
        BigDecimal sum = insuranceRecordMapper.sumPremiumByVehicleId(vehicleId);
        return sum == null ? BigDecimal.ZERO : sum;
    }

    @Override
    public Integer countInsuranceByVehicleId(Long vehicleId) {
        if (vehicleId == null) {
            log.error("统计车辆保险数量失败: vehicleId不能为空");
            return 0;
        }
        Integer count = insuranceRecordMapper.countInsuranceByVehicleId(vehicleId);
        return count == null ? 0 : count;
    }

    @Override
    public List<Map<String, Object>> statisticsByType() {
        return insuranceRecordMapper.statisticsByType();
    }

    @Override
    public List<Map<String, Object>> statisticsByYear() {
        return insuranceRecordMapper.statisticsByYear();
    }

    /**
     * 设置保险状态
     * 1-有效，2-即将到期(30天内)，3-已过期
     *
     * @param insurance 保险记录
     */
    private void setInsuranceStatus(InsuranceRecord insurance) {
        if (insurance.getEndTime() != null) {
            LocalDateTime now = LocalDateTime.now();
            if (insurance.getEndTime().isBefore(now)) {
                insurance.setStatus(3); // 已过期
            } else {
                long days = ChronoUnit.DAYS.between(now, insurance.getEndTime());
                if (days <= 30) {
                    insurance.setStatus(2); // 即将到期
                } else {
                    insurance.setStatus(1); // 有效
                }
            }
        } else {
            // 如果没有设置到期时间，默认为有效
            insurance.setStatus(1);
        }
    }
} 